/*
 * $Id: JobDirRequestData.java,v 1.3 2009/06/25 15:50:13 afaichun Exp $
 * 
 * Copyright (C) 2008 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.processor.shemjob;

import java.io.File;
import java.util.Hashtable;
import java.util.Iterator;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.database.pojo.ActFileTransferDetails;
import com.ge.healthcare.autosc.common.database.pojo.ActTask;
import com.ge.healthcare.autosc.common.exceptions.BasicException;
import com.ge.healthcare.autosc.common.util.dataItem.ASCTextFileDataItem;
import com.ge.healthcare.autosc.common.util.dataItem.IASCTextDataItem;
/**
 * This class constructs task-level directory in the job directory.
 * The task directory is assumed to be under request-level directory
 * under the jobdir even though this class would not enforce it.
 * 
 * After the class is constructed, it allows caller to register files
 * that are under the constructed directory to this class. All files should
 * be physically under the constructed directory before registering them into
 * the class, or they will be rejected with exception.
 * 
 * @author 212042946
 *
 */
public class JobDirRequestData {

	private Hashtable<String, IASCTextDataItem> dataItemHash = new Hashtable<String, IASCTextDataItem>();
	private Hashtable<String, ActFileTransferDetails> ftDetailsHash = new Hashtable<String, ActFileTransferDetails>();
	
	private File taskJobDir = null;

	/**
	 * Constructor
	 * @param task	ActTask
	 * @param jobDir	jobDir directory object
	 * @throws BasicException Failed to create task-level sub-directory under incoming 
	 *         jobDir directory
	 */
	public JobDirRequestData(ActTask task, File jobDir) 
		throws BasicException {
		if(task != null && jobDir != null) {
			File theJobDir = new File(jobDir, task.getTaskId().toString());
			if(theJobDir.exists() == false) {
				if(theJobDir.mkdir() == false) {
					throw new BasicException("Failed createing job directory " + theJobDir.getPath());
				}
			}
			taskJobDir = theJobDir;
		}
	}
	
	/**
	 * Create and return IASCTextDataItem object pointing to the file sitting
	 * under the constructed jobDir in the object. This method generates
	 * the file object without validating file is physically located under
	 * the jobdir directory.
	 * @param fileName
	 * @return IASCTextDataItem object
	 * @throws BasicException
	 */
	public IASCTextDataItem newDataFile(String fileName) 
		throws BasicException {
		verifyJobDirExist();
		return new ASCTextFileDataItem(taskJobDir, fileName);
	}
	
	/**
	 * Register data item to this object. This method requires the registering file
	 * is physically located in the jobDir directory.
	 * @param sourceItemId Reference key to the file
	 * @param dataItem	IASCTextDataItem referencing the registering file
	 * @param ftDetail	ActFileTransferDetails referencing the registering file
	 * @throws BasicException	File does not exist in the jobdir
	 */
	public void addDataItem(String sourceItemId, IASCTextDataItem dataItem, ActFileTransferDetails ftDetail) 
		throws BasicException {
		verifyFileExist(dataItem);
		dataItemHash.put(sourceItemId, dataItem);
		ftDetailsHash.put(sourceItemId, ftDetail);
	}
	
	/**
	 * Retrieve data item by key
	 * @param key	Reference key that was used for registering the file.
	 * @return	IASCTextDataItem
	 */
	public IASCTextDataItem getDataItem(String key) {
		return (IASCTextDataItem)dataItemHash.get(key);
	}
	
	/**
	 * Retrieve ActFileTransferDetails object by key
	 * @param key	Reference key that was used for registering the file.
	 * @return ActFileTransferDetails
	 */
	public ActFileTransferDetails getFtDetails(String key) {
		return (ActFileTransferDetails)ftDetailsHash.get(key);
	}
	
	public String toString() {
		StringBuffer msg = new StringBuffer();
		msg.append("{jobdir=").append(this.taskJobDir.getPath()).append("}");
		msg.append("{Registered files:");
		Iterator<String> iter = dataItemHash.keySet().iterator();
		while(iter.hasNext()) {
			msg.append("{name=").append((String)iter.next()).append("}");
		}
		msg.append("}").append("\n");
		return msg.toString();
	}
	
	private void verifyJobDirExist() throws BasicException {
		if(taskJobDir != null) {
			if(taskJobDir.exists() == false) {
				ASCLogger.warn(this.getClass(), "verifyJobDirExist", "taskJobDir does not exist when it was previosly created. Try to create it now..");
				// Does not exist for some reason, try to make one.
				if(taskJobDir.mkdir() == false) {
					throw new BasicException("Job directory " + taskJobDir.getPath() + " does not exist");
				}
			}
		} else {
			throw new BasicException("Job directory is not defined");
		}
	}
	
	private void verifyFileExist(IASCTextDataItem dataItem) throws BasicException {
		verifyJobDirExist();
		File dataFile = dataItem.getDataSourceFile();
		File jobDirFile = new File(taskJobDir, dataFile.getName());
		if(!jobDirFile.exists()) {
			throw new BasicException("File " + dataFile.getPath() + " does not exist under jobdir " +
					taskJobDir.getPath());
		}
	}
}
